﻿using System;
using System.Collections.Generic;
using NGinnBPM.Services;
using System.IO;
using NLog;
using System.Text;
using NGinnBPM.MessageBus;
using System.IO;

namespace NGinnBPM.Services.Utilities
{
    public class BarrierRegistry : IBarrierRegistry
    {
        private Dictionary<string, string> _dic = new Dictionary<string, string>();
        private IMessageBus _bus;
        
        #region IBarrierRegistry Members

        private string key(string processDef, string task)
        {
            return string.Format("{0}_{1}.barrier", processDef, task);
        }
        
        /// <summary>
        /// Internal nginn message bus
        /// </summary>
        public IMessageBus MessageBus
        {
            get { return _bus; }
            set { _bus = value; }
        }

        /// <summary>
        /// Base directory where barriers are stored
        /// </summary>
        public string BaseDirectory { get; set; }


        /// <summary>
        /// TODO: If a barrier is removed, paused tasks should be rescheduled
        /// </summary>
        /// <param name="processDefId"></param>
        /// <param name="taskId"></param>
        /// <param name="enable"></param>
        public void SetBarrier(string processDefId, string placeId, bool enable)
        {
            if (!Directory.Exists(BaseDirectory)) Directory.CreateDirectory(BaseDirectory);
            string pth = Path.Combine(BaseDirectory, key(processDefId, placeId));
            if (enable)
            {
                if (File.Exists(pth)) return;
                using (FileStream fs = new FileStream(pth, FileMode.Create, FileAccess.Write))
                {
                    byte[] data = Encoding.Default.GetBytes(DateTime.Now.ToString());
                    fs.Write(data, 0, data.Length);
                }
            }
            else
            {
                if (File.Exists(pth))
                {
                    File.Delete(pth);
                    if (MessageBus != null)
                    {
                        BarrierRemovedEvent bre = new BarrierRemovedEvent();
                        bre.ProcessDefinitionId = processDefId;
                        bre.PlaceId = placeId;
                        MessageBus.Notify(bre);
                    }
                }
            }
                    
        }

        public bool GetBarrier(string processDefId, string taskId)
        {
            string pth = Path.Combine(BaseDirectory, key(processDefId, taskId));
            return File.Exists(pth);
        }

        public IList<string> GetAllBarriers()
        {
            return new List<string>(Directory.GetFiles(BaseDirectory, "*.barrier"));
        }

        #endregion
    }
}
